package com.licheedev.mydialogfragment;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import java.lang.reflect.Field;

/**
 * 修改过的DialogFragment,只需要重写 {@link #onCreateDialog(Bundle)}, {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} 直接返回Dialog的rootView，而且运行时不会崩溃
 */
public class ModifiedDialogFragment extends DialogFragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
        @Nullable Bundle savedInstanceState) {
        Dialog dialog = requireDialog();
        return getDialogRootView(dialog);
    }

    protected View getDialogRootView(Dialog dialog) {
        return ((ViewGroup) dialog.findViewById(android.R.id.content)).getChildAt(0);
    }

    private final Observer<LifecycleOwner> mObserver = new Observer<LifecycleOwner>() {
        @SuppressLint("SyntheticAccessor")
        @Override
        public void onChanged(LifecycleOwner lifecycleOwner) {
            if (lifecycleOwner != null && getShowsDialog()) {
                View view = requireView();
                if (view.getParent() != null) {
                    return;
                }

                Dialog dialog = getDialog();
                if (dialog != null) {
                    dialog.setContentView(view);
                }
            }
        }
    };

    @Override
    public void onAttach(@NonNull Context context) {
        modifyObserver(); // 在使用mObserver对象之前修改mObserver对象
        super.onAttach(context);
    }

    /** 通过放射修改mObserver属性内容 */
    private void modifyObserver() {
        try {
            Field field = DialogFragment.class.getDeclaredField("mObserver");
            field.setAccessible(true);
            field.set(this, mObserver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
